﻿using System;
using System.Collections;
using System.Globalization;
using System.Windows;
using System.Windows.Media;
using TeBigCommonUI.Common;
using Timer = System.Windows.Threading.DispatcherTimer;

namespace TeBigCommonUI.Items
{
    public class MarqueeNewsControl : SimpleNewsControl
    {
        public class News
        {
            public string Title { get; set; }
            public string Content { get; set; }
            public DateTime DateTime { get; set; }
        }

        private double CurrentPosition { get; set; }

        private Timer Timer { get; set; }

        private double LoopSpace { get { return ActualHeight / 10; } }

        private const double DefaultFontSize = 24;



        public Brush DeptBrush
        {
            get { return (Brush)GetValue(DeptBrushProperty); }
            set { SetValue(DeptBrushProperty, value); }
        }

        // Using a DependencyProperty as the backing store for DeptBrush.  This enables animation, styling, binding, etc...
        public static readonly DependencyProperty DeptBrushProperty =
            DependencyProperty.Register("DeptBrush", typeof(Brush), typeof(MarqueeNewsControl), new PropertyMetadata(null));



        public MarqueeNewsControl()
        {
            Foreground = BrushHelper.CreateLinearGradientBrush(Color.FromArgb(0xfF, 0xff, 0x3c, 0x24), 0.2, 0.3, 90);
            DeptBrush = BrushHelper.CreateLinearGradientBrush(Color.FromArgb(0xfF, 0xff, 0x3c, 0x24), 0.2, 0.3, 90);

            CurrentPosition = int.MinValue;

            FontSize = DefaultFontSize;

            Timer = new Timer();

            Timer.Interval = new TimeSpan(0, 0, 1);
            Timer.Tick += Timer_Tick;
        }

        protected override void OnInitControl()
        {
            base.OnInitControl();

            Timer.Start();
        }

        private void Timer_Tick(object sender, EventArgs e)
        {
            CurrentPosition -= 10;

            InvalidateVisual();
        }

        protected FormattedText CreateFormattedText(string text, FontWeight fw, double max_width, Brush brush)
        {
            var ft = new FormattedText(text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight,
                     new Typeface(this.FontFamily, this.FontStyle, fw, this.FontStretch),
                     this.FontSize, brush);

            ft.TextAlignment = TextAlignment.Left;
            ft.MaxTextWidth = Math.Max(1, max_width);

            return ft;
        }

        protected void RenderNews(DrawingContext dc, int index, News news, ref double y)
        {
            double x = 0;

            FormattedText ftIndex = CreateFormattedText($"{index + 1,2}. ", FontWeights.Bold, ActualWidth - x, this.DeptBrush);
            dc.DrawText(ftIndex, new Point(x, y));
            x += 38;

            FormattedText ftTitle = CreateFormattedText($"{news.Title + ":"}", FontWeights.Normal, ActualWidth - x, this.DeptBrush);
            dc.DrawText(ftTitle, new Point(x, y));
            x += 138;

            FormattedText ftContent = CreateFormattedText($"{news.DateTime:yyyy年MM月dd日HH时mm分}, {news.Content}"
                , FontWeights.Black, ActualWidth - x, this.Foreground);
            dc.DrawText(ftContent, new Point(x, y));

            y += ftContent.Height + 22;
        }

        protected override void OnRender(DrawingContext dc)
        {
            base.OnRender(dc);

            if (DataSource is IList NewsCollection)
            {
                if (CurrentPosition == int.MinValue)
                    CurrentPosition = ActualHeight / 10;

                dc.PushClip(new RectangleGeometry(new Rect(RenderSize)));
                dc.PushTransform(new TranslateTransform(0, CurrentPosition));

                double y1 = 0, y2 = 0, y2_begin = 0;

                for (int i = 0; i < NewsCollection.Count; i++)
                {
                    var item = NewsCollection[i];

                    var news = new News
                    {
                        Title = item.FastGetProperty(TitleDataMember).ToString(),
                        Content = item.FastGetProperty(ContentDataMember).ToString(),
                        DateTime = Convert.ToDateTime(item.FastGetProperty(DateTimeDataMember)),
                    };

                    RenderNews(dc, i, news, ref y1);

                    if (CurrentPosition + y1 > ActualHeight)
                        break;
                }

                if (CurrentPosition + y1 < (ActualHeight - LoopSpace))
                {
                    y2_begin = y2 = y1 + LoopSpace;

                    for (int i = 0; i < NewsCollection.Count; i++)
                    {
                        var item = NewsCollection[i];

                        var news = new News
                        {
                            Title = item.FastGetProperty(TitleDataMember).ToString(),
                            Content = item.FastGetProperty(ContentDataMember).ToString(),
                            DateTime = Convert.ToDateTime(item.FastGetProperty(DateTimeDataMember)),
                        };

                        RenderNews(dc, i, news, ref y2);

                        if (CurrentPosition + y2 > ActualHeight)
                            break;
                    }
                }

                if (CurrentPosition + y1 < 0 && y2_begin != 0)
                    CurrentPosition = y2_begin - y1;
            }
        }
    }
}